﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Collections;

namespace homework81
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private ArrayList list = new ArrayList(); //存输入的数字和运算符
        private bool op_flag = false; //是否可以输入加减乘除
        private bool num_flag = true; //是否可以输入数字
        private bool neg_flag = true; //是否可以输入负号,即负数，但程序里没有实现，先保留，后续可以改进
        private bool dot_flag = true; //是否可以输入小数点
        private bool is_clear = true; //是否清除
        private void inputNumber(object sender, EventArgs e)
        {   //如果处于可以清除状态，直接全部清除
            if (is_clear) input_Delete(this.butClear, e);
            if (num_flag)
            {
                //如果输入的是点
                if (sender == butdot)
                {
                    //但此时不能输入点
                    if (!dot_flag) return;
                    dot_flag = false;
                    // 防止出现 以.开头的数
                    if (this.result.Text.Length > 0)
                        this.result.Text += ".";
                    else
                        this.result.Text += "0.";
                }
                else
                {
                    // 防止出现 01等0开头的数
                    if (this.result.Text.Length < 2 && this.result.Text[0] == '0')
                        this.result.Text = "";
                    this.result.Text += ((Button)sender).Text;

                }
                // 处理哪些按钮接下去可用
                neg_flag = true;
                op_flag = true;
            }
        }
        private void input_Op(object sender, EventArgs e)
        {
            if (op_flag)
            {
                // 处理显示时的小细节，若之前输入的不是是单目运算符，就加上数字和运算符，否则就只显示运算符。
                if (neg_flag == true)
                {
                    this.textResult.Text += (this.result.Text + ((Button)sender).Text);
                    list.Add(Double.Parse(this.result.Text));
                }
                else
                    this.textResult.Text += (((Button)sender).Text);

                list.Add(((Button)sender).Text);

                // 处理哪些按钮接下去可用
                op_flag = false;
                neg_flag = false;
                num_flag = true;
                dot_flag = true;
                //置0，可以继续输入
                this.result.Text = "0";
            }
        }

       
        
        private void input_Delete(object sender, EventArgs e)
        {   //所有数据全部清除
            if (sender == butClear)
            {
                this.textResult.Text = "";
                this.result.Text = "0";
                op_flag = neg_flag = false;
                num_flag = true;
                //清空存放的数组
                list.Clear();
                is_clear = false;

            }
            //只清空下面每次的输入框，清空一个输入
            if (sender == ce)
            {
                this.result.Text = "0";
            }
            dot_flag = true;
        }
        //数据结构知识，中缀转后缀。传入的参数是一个字符串。
        private Queue<string> change(string str)
        {
            string temp = "";
            string str1 = "";
            Stack<string> s = new Stack<string>();
            Queue<string> que = new Queue<string>();

            int i;
            for (i = 0; i < str.Length; i++)
            {
                temp = "";
                //扫描到的是数字或者加号
                if (((i == 0) && (str[i] == '+'
                                  )) || (str[i] >= '0' && str[i] <= '9'))
                {    //越界
                    if (i >= str.Length)
                        break;
                    while (i < str.Length && (((i == 0)
                                               && (str[i] == '+')) || (str[i] >= '0' && str[i] <= '9' || str[i] == '.')))
                    {
                        if (str[i] != '+')
                            temp += str[i];
                        i++;
                    }
                    if (temp.Length > 0)
                        que.Enqueue(temp);
                }
                if (i >= str.Length) break;
                //由于没有括号，优先级一定大于栈顶优先级，直接入栈
                if (str[i] == '*' || str[i] == '/' || str[i] == '%')
                {
                    str1 = str[i].ToString();
                    s.Push(str1);
                }
                else if (str[i] == '+' || str[i] == '-')
                {
                    if (s.Count() == 0)
                    {
                        str1 = str[i].ToString();
                        s.Push(str1);
                    }
                    else
                    {
                        do
                        {
                            str1 = s.Peek();
                            s.Pop();
                            que.Enqueue(str1);

                        } while (s.Count() != 0);
                        str1 = str[i].ToString();
                        s.Push(str1);
                    }
                }
                str1 = "";
            }
            while (s.Count() > 0)
            {
                str1 = s.Peek();
                s.Pop();
                que.Enqueue(str1);
            }

            return que;
        }



        private void textResult_TextChanged(object sender, EventArgs e)
        {

        }

        private void butEqual_Click(object sender, EventArgs e)
        {
            if (!op_flag) return;
            //加入最后一个输入的数字
            list.Add(Double.Parse(result.Text));
            if (!result.Text.Equals("0"))
                textResult.Text += result.Text;
            try
            {
                string str = "";
                // 把输入的表达式转成字符串。
                foreach (var val in list)
                {
                    str = str + val.ToString();
                }
                // 获取后缀表达式，用队列形式存储。
                Queue<string> que = change(str);
                Double num1, num2;
                string ans;
                Stack<Double> st = new Stack<double>();

                foreach (var val in que)
                {
                    // 因为que里面要么是运算符要么是数值
                    if (val[0] >= '0' && val[0] <= '9')
                    {
                        st.Push(Double.Parse(val));
                    }
                    else
                    {
                        Double num = 0;
                        num1 = st.Pop();
                        num2 = st.Pop();
                        char op = val[0];
                        if (op == '+') num = num1 + num2;
                        if (op == '-') num = num2 - num1;
                        if (op == '*') num = num1 * num2;
                        if (op == '%')
                        {
                            if (num1 == 0)
                            {
                                textResult.Text = "输出不能为零";
                                return;
                            }
                            num = num2 % num1;
                        }
                        if (op == '/')
                        {
                            if (num1 == 0)
                            {
                                textResult.Text = "输出不能为零";
                                return;
                            }
                            num = num2 / num1;
                        }
                        st.Push(num);
                    }
                }
                ans = st.Peek().ToString();
                textResult.Text += "=" + ans;

            }
            catch (Exception exce)
            {
                textResult.Text = exce.Message;
            }
            finally
            {
                is_clear = true;
            }

        }
    }
}
